package cn.s1995.sloth.bizs.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.s1995.sloth.bizs.constant.BizCst;
import cn.s1995.sloth.common.core.constant.enums.hint.Hint;
import cn.s1995.sloth.bizs.entity.Order;
import cn.s1995.sloth.bizs.entity.OrderItem;
import cn.s1995.sloth.bizs.entity.OrderRefund;
import cn.s1995.sloth.bizs.exception.BizException;
import cn.s1995.sloth.bizs.mapper.OrderRefundMapper;
import cn.s1995.sloth.bizs.oo.req.OrderRefundItemREQ;
import cn.s1995.sloth.bizs.oo.req.OrderRefundREQ;
import cn.s1995.sloth.bizs.oo.req.OrderRefundVerifyREQ;
import cn.s1995.sloth.bizs.service.OrderItemService;
import cn.s1995.sloth.bizs.service.OrderRefundService;
import cn.s1995.sloth.bizs.service.OrderService;
import cn.s1995.sloth.common.security.util.SecurityUtils;
import cn.s1995.sloth.common.sequence.sequence.Sequence;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 订单退款
 *
 * @author Lex
 * @date 2023-12-29 03:07:41
 */
@Service
public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, OrderRefund> implements OrderRefundService {

    @Resource
    private OrderItemService orderItemService;

    @Resource
    private OrderService orderService;

    @Resource
    private Sequence refundSequence;

    @Override
    @Transactional
    public void refund(OrderRefundREQ req) {
        if (ObjectUtil.isNotNull(req.getOrderId()) && ObjectUtil.isNotEmpty(req.getItems())) {
            Long uid = SecurityUtils.getUser().getId();
            // 暂时限定同一订单
            Order order = orderService.getById(req.getOrderId());
            // 订单状态限制
            if (ObjectUtil.isNull(order) || (order.getState() != BizCst.Order.State.paid && order.getState() != BizCst.Order.State.confirm && order.getState() != BizCst.Order.State.completed))
                throw new BizException(Hint.FORBIDDEN);
            for (OrderRefundItemREQ ori : req.getItems()) {
                OrderItem item = orderItemService.getById(ori.getOrderItemId());
                if (ObjectUtil.isNull(item) || !uid.equals(item.getUid()))
                    throw new BizException(Hint.APP_YOU_HAVE_NO_PERMISSION_TO_GET_THE_ORDER_INFORMATION);
                // 判断是否已经申请过退款
                long count = count(
                        Wrappers.lambdaQuery(OrderRefund.class)
                                .eq(OrderRefund::getOrderItemId, ori.getOrderItemId())
                                .ne(OrderRefund::getState, BizCst.OrderRefund.State.cancel)
                );
                if (count > 0) {
                    throw new BizException(Hint.APP_THE_ORDER_REFUND_EXISTED);
                }
                save(
                        OrderRefund.builder()
                                .id(Long.valueOf(refundSequence.nextNo()))
                                .uid(uid)
                                .shopId(item.getShopId())
                                .orderId(item.getOrderId())
                                .orderItemId(ori.getOrderItemId())
                                .orderAmount(order.getActualAmount())
                                .payMethod(order.getPayMethod())
                                .flowTradeNo(ObjectUtil.isNotNull(order.getTransactionId()) ? order.getTransactionId() : order.getPayFlowId().toString())
                                .state(BizCst.OrderRefund.State.refunding)
                                .processState(BizCst.CommonAuditState.toBeAudit)
                                .num(item.getNum())
                                .amount(item.getTotalAmount())
                                .applyType(ori.getApplyType())
                                .pics(ori.getPics())
                                .reason(ori.getReason())
                                .build()
                );
            }
        }
    }

    @Override
    public void cancel(List<Long> ids) {
        this.update(
                Wrappers.lambdaUpdate(OrderRefund.class)
                        .eq(OrderRefund::getUid, SecurityUtils.getUser().getId())
                        .in(OrderRefund::getOrderItemId, ids)
                        .eq(OrderRefund::getState, BizCst.OrderRefund.State.refunding)
                        .eq(OrderRefund::getProcessState, BizCst.CommonAuditState.toBeAudit)
                        .set(OrderRefund::getState, BizCst.OrderRefund.State.cancel)
        );
    }

    @Override
    public void verify(OrderRefundVerifyREQ req) {
//        OrderRefund refund = this.getById(req.getId());
//        if (ObjectUtil.isNull(refund))
//            throw new BizException(Hint.NOT_FOUND);
//        if (Boolean.TRUE.equals(req.getIsApprove())) {
//            // TODO 审核通过，调用退款接口
//            RefundREQ refundREQ = new RefundREQ();
//            refundREQ.setRefundId(req.getId());
//            refund.setProcessState(BizCst.CommonAuditState.approve);
//            refund.setApprovedTime(LocalDateTime.now());
//        } else {
//            refund.setProcessState(BizCst.CommonAuditState.reject);
//            refund.setRejectReason(req.getRejectReason());
//            refund.setRejectTime(LocalDateTime.now());
//            refund.setState(BizCst.OrderRefund.State.failure);
//        }
//        this.updateById(refund);
    }
}
